<?php

namespace App\Http\Controllers\Common;

use App\Helpers\Price;
use App\Helpers\utils\WeChat\AiSpeech;
use App\Helpers\utils\WeChat\OfficialAccount;
use App\Http\Controllers\Controller;
use App\Models\Keyword;
use App\Models\Music;
use App\Models\Setting;
use App\Models\User;
use App\Models\WxLog;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class WeChatController extends Controller
{
    /**
     * 公众号接入
     * @param Request $request
     * @return mixed
     */
    public function checkToken(Request $request)
    {
        $signature = $request->get('signature');
        $timestamp = $request->get('timestamp');
        $nonce = $request->get('nonce');
        $echostr = $request->get('echostr');
        $wechat = new OfficialAccount();
        $setting = Setting::where('key', 'token')->first();
        if (empty($setting)) {
            $token = config('wx.token');
        } else {
            $token = $setting['value'];
        }
        return $wechat->checkToken($signature, $timestamp, $nonce, $echostr, $token);
    }

    public function reply(Request $request)
    {
        $dataType = ['array', 'string'];
        # TODO 目前只回复纯文字消息
        $wx = new OfficialAccount();
        $xml = $request->getContent();
        $data = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS);
        $params = $wx->objToArr($data);
        $fromUser = $params['FromUserName'];     // 用户openid
        $rspData = $params;
        $rsp = null;
        // 用户打开订阅号，记录用户信息
        $user = User::where('openid', $fromUser)->first();
        if (empty($user)) {
            $user = new User();
            $user['openid'] = $fromUser;
            $user['subscribe_status'] = 1;
        }
        $userInfo = $wx->getUserInfoByOpenid($fromUser);
        try {
            if (!empty($userInfo['unionid'])) {
                $user['unionid'] = $userInfo['unionid'];
            }
            $user['nickname'] = $userInfo['nickname'];
            $user['gender'] = $userInfo['sex'];
            $user['country'] = $userInfo['country'];
            $user['province'] = $userInfo['province'];
            $user['city'] = $userInfo['city'];
            $user['avatar'] = $userInfo['headimgurl'];
            $user['subscribe_scene'] = $userInfo['subscribe_scene'];
            $user['remark'] = $userInfo['remark'];
        } catch (\Exception $exception) {
            Log::error('无法获取用户信息');
            Log::error($userInfo);
        }

        try {
            // 判断当前用户信息当天有没有更新过，有就不再更新
            $updateAt = $user['updated_at'];
            if (strpos($updateAt, date('Y-m-d')) === false) {
                $user['updated_at'] = date('Y-m-d H:i:s');
                $user->save();
            }
        } catch (\Exception $exception) {
            Log::error('用户信息保存出错');
        }

        /**
         * 接收事件推送：订阅，取消订阅
         * 1 关注/取消关注事件
         * 2 扫描带参数二维码事件
         * 3 上报地理位置事件
         * 4 自定义菜单事件
         * 5 点击菜单拉取消息时的事件推送
         * 6 点击菜单跳转链接时的事件推送
         */
        if ($params['MsgType'] == 'event') {
            $log = new WxLog();
            $log['openid'] = $fromUser;
            $log['event'] = $params['Event'];
            $log['remark'] = json_encode($params['EventKey']);
            try {
                switch ($params['Event']) {
                    case 'subscribe': {
                        // 订阅
                        Log::info('用户【' . $fromUser . '】关注了公众号。');
                        if (empty($user['nickname'])) {
                            $name = '您';
                        } else {
                            $name = $user['nickname'];
                        }
                        $reply = '感谢您的关注，非常荣幸【' . $name . '】能够加入本村。本村致力于为各位村民提供非常可口下饭的' .
                            '时评、趣事等【精选内容】以及各种【好玩】的小东西，更多好玩好看的内容留待各位村民自行探索哦~';
                        $rspData['Reply'] = $reply;
                        $rsp = $wx->textMsg($rspData);
                        $log->save();
                        break;
                    }
                    case 'unsubscribe': {
                        // 取消订阅
                        Log::info('用户【' . $fromUser . '】取消关注。');
                        $user['subscribe_status'] = 0;
                        $user->save();
                        $log->save();
                        return '';
                    }
                    case 'SCAN': {
                        // 扫描带参数二维码事件（已关注情况下）
                        Log::info('用户【' . $fromUser . '】触发了场景事件。');
                        $log->save();
                        return '';
                    }
                    case 'LOCATION': {
                        // 上报地理位置事件
                        Log::info('用户【' . $fromUser . '】上报地理位置。');
                        $longitude = $params['Longitude'];
                        $latitude = $params['Latitude'];
                        $log->save();
                        return '';
                    }
                    case 'CLICK': {
                        // 自定义菜单事件
                        Log::info('用户【' . $fromUser . '】点击了菜单。');
                        $log->save();
                        return '';
                    }
                    case 'VIEW': {
                        // 自定义菜单事件，只有手机端有推送，PC端无推送
                        Log::info('用户【' . $fromUser . '】点击了VIEW菜单。');
                        $log->save();
                        return '';
                    }
                    default: {
                        Log::debug($params['Event']);
                        $log->save();
                        return '';
                    }
                }
            } catch (\Exception $exception) {
                Log::error('转换出错');
                Log::error($exception->getMessage());
            }
        } else {
            // 接收普通消息
            switch ($params['MsgType']) {
                case 'text': {
                    $content = $params['Content'];
                    $m = Keyword::where(function ($q) use ($content) {
                        $q->where('word', $content)
                            ->where('type', 1);
                    })->orWhere(function ($q) use ($content) {
                        $q->where('word', 'like', "%$content%")
                            ->where('type', 2);
                    })->first();
                    $status = true;
                    $reply = null;
                    if (empty($m)) {
                        // 判断是否是京东淘宝链接
                        preg_match_all("#\bhttps?://[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#",
                            $content,
                            $results
                        );
                        if (count($results) == 0 || count($results[0]) == 0) {
                            // 不包含链接，接入微信对话开发平台
                            $ai = new AiSpeech();
                            $result = $ai->bot($content);
                            $ran = 1;
                            $msg = $result['msg'][0];
                            switch ($result['answer_type']) {
                                case 'text': {
                                    $reply = $msg['content'];
                                    break;
                                }
                                case 'music': {

                                }
                                case 'news': {
                                    $reply = $this->botInfo2Article($result, $dataType[$ran]);
                                    if ($ran == 0) {
                                        $status = false;
                                        $rsp = $wx->articleMsg($params, $reply);
                                    }
                                    break;
                                }
                            }
                        } else {
                            $p = new Price();
                            $url = $results[0][0];
                            $price = $p->getPrice($url);
                            if ($price == []) {
                                $reply = '该商品暂未收录';
                            } else {
                                $reply = '【' . $price['website'] . '】' . $price['title'] . "\n" .
                                    "🔹【历史最低价】\n    " . $price['lowestDate'] . ' ￥' . $price['lowestPrice'] . "\n" .
                                    "🔹【近30天最低价】\n    " . $price['lowest'] . "\n" .
                                    "🔹【近30天最高价】\n    " . $price['highest'] . "\n" .
                                    "🔹【近7天价格】\n    ";
                                $last7day = '';
                                foreach ($price['items'] as $item) {
                                    $last7day .= $item[0] . ' ￥' . $item[1] . "\n    ";
                                }
                                $reply .= $last7day;
                            }
                        }

                    } else {
                        // 存在关键字回复
                        # TODO 回复消息类型，图文，音频，图片，视频等
                        $reply = $m['content'];
                    }
                    if ($status) {
                        $rspData['Reply'] = $reply;
                        $rsp = $wx->textMsg($rspData);
                    }
                    break;
                }
                case 'image': {
                    # TODO 图片识别功能
                    // break;
                }
                case 'voice': {
                    # TODO 语音识别
                    // break;
                }
                case 'video': {
                    // break;
                }
                case 'shortvideo': {
                    // break;
                }
                case 'location': {
                    // break;
                }
                case 'link': {
                    // break;
                }
                default: break;
            }
        }
        return $wx->responseXml($rsp);
    }

    /**
     * 自定义菜单
     * @param Request $request
     * @return array|int[]
     */
    public function menu(Request $request)
    {
        $wx = new OfficialAccount();
        $menus = [
            'button' => [
                [
                    'name' => '精选内容',
                    'sub_button' => [
                        [
                            'name' => '饭前聊一会儿',
                            'type' => 'view',
                            'media_id' => 'https://www.chasingworld.cn'
                        ]
                    ]
                ],
                [
                    'name' => '好玩',
                    'sub_button' => [
                        [
                            'name' => '决定助手',
                            'type' => 'miniprogram',
                            'url' => 'https://www.chasingworld.cn',
                            'app_id' => 'wx286b93c14bbf93aa',
                            'pagepath' => 'page/index/index'
                        ],
                        [
                            'name' => '查询历史价格',
                            'type' => 'media_id',
                            'media_id' => 'Virckegf6B_LzBOXdGxKT3ejAXbb_koBExIDngrcMEQ'
                        ],
                        [
                            'name' => '免费听音乐',
                            'type' => 'media_id',
                            'media_id' => 'Virckegf6B_LzBOXdGxKT3ejAXbb_koBExIDngrcMEQ'
                        ]
                    ]
                ],
                [
                    'name' => '更多',
                    'sub_button' => [
                        [
                            'name' => '商务合作',
                            'type' => 'view',
                            'url' => 'https://www.chasingworld.cn'
                        ],
                        [
                            'name' => '关于我们',
                            'type' => 'view',
                            'url' => 'https://www.chasingworld.cn'
                        ]
                    ]
                ],
            ]
        ];

        return $wx->menuCreate($menus);
    }

    /**
     * 微信只能对话接口信息转公众号消息
     * @param $data
     * @param string $dataType: 返回的数据格式，可取值，array, string
     * @return array
     */
    private function botInfo2Article($data, $dataType = 'array')
    {
        $type = $data['answer_type'];
        if ($dataType == 'array') {
            $results = [];
        } else {
            $results = '';
        }
        if (!empty($data['more_info'])) {
            $more = $data['more_info'];
            $more = json_decode($more[array_keys($more)[0]], true);
            switch ($type) {
                case 'music': {
                    $items = $more['play_command']['play_list'];
                    $items = array_slice($items, 0 , 8);
                    if ($dataType == 'array') {
                        $results = [];
                        foreach ($items as $item) {
                            $result = [
                                'Title' => $item['name'] . '-' . $item['author'],
                                'Description' => '该歌曲的专辑为：' . $item['album_name'],
                                'PicUrl' => $item['album_pic_url'],
                                'Url' => $item['url']
                            ];
                            $results[] = $result;
                        }
                    } else {
                        $results = '';
                        foreach ($items as $item) {
                            $music = Music::where('mid', $item['mid'])->first();
                            if (empty($music)) {
                                $music = new Music();
                                $music['mid'] = $item['mid'];
                                $music['title'] = $item['name'];
                                $music['author'] = $item['author'];
                                $music['album'] = $item['album_name'];
                                $music['cover'] = $item['album_pic_url'];
                                $music['url'] = $item['url'];
                                $music->save();
                            }

                            $result = '<a href="' . config('app.url') . '/web/music?id=' . $music['id'] . '">' .
                                $item['name'] . '-' . $item['author'] . "</a>\n\n";
                            $results .= $result;
                        }
                    }
                    break;
                }
                case 'news': {
                    $items = $more['data']['docs'];
                    $items = array_slice($items, 0 , 5);
                    $baseUrl = 'https://new.qq.com/rain/a/';
                    if ($dataType == 'array') {
                        $results = [];
                        foreach ($items as $item) {
                            $result = [
                                'Title' => $item['title'],
                                'Description' => $item['abs_s'],
                                'PicUrl' => $item['shortcut'],
                                'Url' => $baseUrl . $item['docid']
                            ];
                            $results[] = $result;
                        }
                    } else {
                        $results = '';
                        foreach ($items as $item) {
                            $result = '<a href="' . $baseUrl . $item['docid'] . '">' .
                                $item['title'] . "</a>\n\n";
                            $results .= $result;
                        }
                    }
                    break;
                }
                default: break;
            }
        }
        return $results;
    }
}
